package com.ruoyi.qywx.service;

import cn.hutool.json.JSONUtil;
import com.ruoyi.common.constant.ErrorConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.mybatis.Query;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.qywx.entity.Survey;
import com.ruoyi.qywx.entity.SurveyAnswer;
import com.ruoyi.qywx.getway.keys.QywxKey;
import com.ruoyi.qywx.mapper.SurveyMapper;
import com.ruoyi.qywx.model.vo.ServeyQuestionVo;
import com.ruoyi.qywx.model.vo.SurveyVo;
import com.ruoyi.qywx.model.vo.mvb.MvSurveyAnswer;
import com.ruoyi.qywx.service.inters.SurveyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author : hcl
 * @Date : 2023/9/14 11:31
 */
@Service
public class SurveyServiceImpl implements SurveyService {
    @Resource
    private SurveyMapper surveyMapper;
    @Autowired
    private RedisCache redisCache;

    @Override
    public Survey selectSurveyById(Long id, Long teamId) {
        Survey survey = surveyMapper.selectById(id);
        if (survey == null || !survey.getTeamId().equals(teamId)) {
            return null;
        }
        survey.setQuestions(surveyMapper.selectQuestionBySurveyId(id));
        return survey;
    }

    @Override
    public AjaxResult selectSurveyBySign(Long teamId, String sign, String uuid) {
        String key = QywxKey.RedisKey.activityKey("survey", sign);
        Survey survey = redisCache.getCacheObject(key);
        if (survey != null) {
            redisCache.expire(key, 10, TimeUnit.MINUTES);
        } else {
            survey = querySurveyBySign(teamId, sign);
            if (Objects.isNull(survey)) return AjaxResult.error("问卷不存在");
            redisCache.setCacheObject(key, survey, 10, TimeUnit.MINUTES);
        }
        if (DateUtils.gt(survey.getBeginTime(), new Date())) {
            return AjaxResult.error("活动暂未开始，请耐心等待...");
        }
        if (DateUtils.gt(new Date(), survey.getEndTime())) {
            return AjaxResult.error("活动已结束");
        }
        Integer answerCount = surveyMapper.selectUserAnswerCount(survey.getId(), uuid);
        if (NumberUtils.isTrue(answerCount)) {
            return AjaxResult.error("您已参与过该问卷调研~");
        }
        survey.setQuestions(surveyMapper.selectQuestionBySurveyId(survey.getId()));
        return AjaxResult.success(survey);
    }

    @Transactional
    @Override
    public AjaxResult create(List<ServeyQuestionVo> questions, Long userId,
                             Date start, Date end, Long teamId) {
        Survey survey = Survey.of(questions, userId, start, end, teamId);
        surveyMapper.insert(survey);
        surveyMapper.insertQuestion(survey.getId(), JSONUtil.toJsonStr(questions));
        return AjaxResult.success();
    }

    @Transactional
    @Override
    public AjaxResult edit(Long id, Date start, Date end,
                           List<ServeyQuestionVo> questions, Long teamId) {
        Survey oldSurvey = surveyMapper.selectOne(new Query<Survey>()
                .selectColumn("team_id", "sign", "end_time")
                .id(id));
        if (oldSurvey == null || !oldSurvey.getTeamId().equals(teamId)) {
            return AjaxResult.error(ErrorConstants.NO_PERMISSION);
        }
        if (DateUtils.gt(new Date(), oldSurvey.getEndTime())) {
            return AjaxResult.error("该调研问卷已结束，不能编辑");
        }
        Survey survey = Survey.of(questions, null, start, end, null);
        survey.setId(id);
        surveyMapper.updateById(survey);
        surveyMapper.updateQuestion(id, JSONUtil.toJsonStr(questions));
        String key = QywxKey.RedisKey.activityKey("survey", oldSurvey.getSign());
        if (redisCache.hasKey(key)) {
            redisCache.deleteObject(key);
        }
        return AjaxResult.success();
    }

    @Transactional
    @Override
    public AjaxResult userAnswer(MvSurveyAnswer answer) {
        Survey survey = querySurveyBySign(answer.getId(), answer.getSign());
        if (Objects.isNull(survey)) {
            return AjaxResult.error(ErrorConstants.NO_DATA);
        }
        SurveyAnswer userAnswer = answer.findUserAnswer(survey);
        int answerCount = surveyMapper.selectUserAnswerCount(userAnswer.getSurveyId(), userAnswer.getUuid());
        if (NumberUtils.isTrue(answerCount)) {
            return AjaxResult.error("您已参与过该问卷调研~");
        }
        surveyMapper.insertSurveyAnswer(userAnswer);
        return AjaxResult.success();
    }

    private Survey querySurveyBySign(Long teamId, String sign) {
        return surveyMapper.selectOne(new Query<Survey>()
                .teamId(teamId)
                .eq("sign", sign)
                .isDelete(false)
        );
    }

    @Override
    public List<SurveyVo> list(String keyword, Long teamId) {
        return surveyMapper.selectSurveyList(keyword, teamId);
    }
}
